package com.mimo.comet.provider;

import java.time.Duration;
import java.util.Optional;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.yeauty.pojo.Session;

import com.google.common.base.Objects;
import com.mimo.comet.config.LocalCometServerConfig;
import com.mimo.comet.constants.CometType;
import com.mimo.comet.dao.ISessionDao;
import com.mimo.comet.provider.plugin.HeartBeatStrategy;
import com.mimo.comet.provider.plugin.IHeartBeatPlugIn;
import com.mimo.comet.user.service.IUserService;
import com.mimo.common.listener.IMessage;

@Component
public class DefaultCometHeartBeatPlugIn implements IHeartBeatPlugIn, IMessage {
  private static final Logger log = LoggerFactory.getLogger(DefaultCometHeartBeatPlugIn.class);

  public static final String EXPIRED_TIMEOUT = "20";

  public static final Duration Expired = Duration.ofSeconds(Integer.valueOf(EXPIRED_TIMEOUT));

  /**
   * 此处默认为只有一次心跳失败，就认为断连，心跳超时为 40s
   */
  private static final HeartBeatStrategy DEFAULT_STRATEGY = new HeartBeatStrategy();
  static {
    DEFAULT_STRATEGY.setLoss(0);
    DEFAULT_STRATEGY.setTimeout(Expired);
  }

  @Autowired
  private LocalCometServerConfig localCometServerConfig;

  @Resource
  private IHeartBeatPlugIn selfHeartBeatPlugInService;

  @Autowired
  private IUserService userSerivce;

  @Autowired
  private ISessionDao sessionDao;

  @Override
  public HeartBeatStrategy getStrategy() {
    return DEFAULT_STRATEGY;
  }

  @Override
  public void onExpired(String user, Object delegate) {
    log.warn("用户[{}] 离线异常", user);
    Optional<ISession> opt = sessionDao.findByUid(user);
    opt.ifPresent(session -> {
      if (!Objects.equal(session.getDelegate(), delegate)) {
        if (session.getCometType() == CometType.WebSocket) {
          Session.class.cast(delegate).close();
        } else {
          // TODO 如果后续还有其他类型，可以在此做扩展
        }
      }
    });
    userSerivce.logout(user, null);
  }

  /**
   * 此处入参为 用户ID
   */
  @Override
  public void onMessage(String uid) {
    sessionDao.findByUid(uid).ifPresent(session -> selfHeartBeatPlugInService.onExpired(uid, session.getDelegate()));
  }

  @Override
  public void reset(String user) {
    throw new UnsupportedOperationException("暂不支持重置");
  }

  @Override
  public String getTopic() {
    return localCometServerConfig.getLogicExpiredChannel();
  }

}
